<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">















 
 
 
 
 
 
 
  
  


<html>
  <head>
    <script type="text/javascript" language="JavaScript">
    ORIGINAL_PAGE_PATH = "/appengine/docs/python/config/appconfig.html";
    </script>
    
    
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Python Application Configuration - Google App Engine - Google Code</title>
<script type="text/javascript"><!--
(function(){function a(){this.t={};this.tick=function(c){this.t[c]=(new Date).getTime()};this.tick("start")}var b=new a;window.jstiming={Timer:a,load:b};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;})();

var _tocPath_ = '/appengine/docs/_toc.ezt';
var codesite_token = null;
//--></script>
<link href="../../../../css/codesite.pack.04102009.css" type="text/css" rel="stylesheet"></link>
<script src="../../../../js/codesite_head.pack.04102009.js" type="text/javascript"></script>
<script type="text/javascript">CODESITE_CSITimer['load'].tick('bhs');</script>
<link rel="search" type="application/opensearchdescription+xml" title="Google Code" href="http://code.google.com/osd.xml" />

<!--[if IE]><link rel="stylesheet" type="text/css" href="../../../../css/iehacks.css" /><![endif]-->

    <link href="../../../../css/semantic_headers.css" rel="stylesheet" type="text/css" />
    <link href="../../../css/local_extensions.css" rel="stylesheet" type="text/css" />
  </head>

  <body class="gc-documentation">

    
    
    
</a>

<div id="gb">
 <span>
  
    <a id="lang-dropdown" class="dropdown" href="http://code.google.com" onclick="return false;"><img class="globeicon" src="../../../../images/globe2_small.png"/><span>English</span></a>
  
 </span>
</div>

<div class="gbh" style="left: 0pt;"></div>
<div class="gbh" style="right: 0pt;"></div>


<style type="text/css">
  #gc-topnav h1 {
    padding: 0 0 0 6px;
  }
</style>


<div id="gc-container">
<a name="top"></a>
<div id="skipto">
  <a href="#gc-pagecontent">Skip to page content</a>
  <a href="#gc-toc">Skip to main navigation</a>
</div>

<div id="gc-header">
  <div id="logo"><a href="http://code.google.com">
  
  
     <img src="../../../../images/cleardot.gif" height="1px" width="1px" alt="Google Code Home Page" id="gc-logo-img"/>
  
  
  </a></div>
  <div id="search">
    <div id="searchForm" class="searchForm">
      <form id="cse" action="http://www.google.com/cse" accept-charset="utf-8" class="gsc-search-box" onsubmit="executeGSearch(document.getElementById('gsearchInput').value); return false;">
      <noscript>
      <input type="hidden" name="cref" value="http://code.google.com/cse/googlecode-context.xml"/>
      </noscript>
        <table class="gsc-search-box" cellpadding="0" cellspacing="0">
          <tbody>
            <tr>
              <td class="gsc-input">
                <input id="gsearchInput" type="text" name="q" maxlength="2048" class="gsc-input" autocomplete="off" title="Google Code Search" style="width:345px"/>
              </td>
              <td class="gsc-search-button">
                <div id="cs-searchresults" onclick="event.cancelBubble = true;"></div>
                <input title="Search" id="gsearchButton" class="gsc-search-button" name="sa" value="Search" type="submit"/>
              </td>
            </tr>
            <tr>
              <td colspan="2" class="greytext">e.g. "templates" or "datastore"</td>
            </tr>
          </tbody>
        </table>
      </form>
    </div> <!-- end searchForm -->
  </div> <!-- end search -->
</div> <!-- end gc-header -->


<div id="codesiteContent">

<a name="gc-topnav-anchor"></a>
<div id="gc-topnav">
  <h1>Google App Engine</h1>
  <ul id="docs" class="gc-topnav-tabs">

    <li id="home_link">
      <a href="../../../index.html" title="Google App Engine home page">Home</a>
    </li>
  
    <li id="docs_link">
      <a href="../../index.html" class="selected" title="Official Google App Engine documentation">Docs</a>
    </li>
  
    <li id="faq_link">
      <a href="../../../kb/index.html" title="Answers to frequently asked questions about Google App Engine">FAQ</a>
    </li>
  
    <li id="articles_link">
      <a href="../../../articles/index.html" title="Focused articles and tutorials for Google App Engine developers">Articles</a>
    </li>
  
    <li>
      <a href="http://googleappengine.blogspot.com/" title="Official Google App Engine blog">Blog</a>
    </li>
  
    <li>
      <a href="../../../community.html" title="Community home for Google App Engine">Community</a>
    </li>
  
    <li>
      <a href="../../../terms.html" title="Google App Engine terms of service">Terms</a>
    </li>
  
    <li>
      <a href="../../../downloads.html" title="Download Google App Engine">Download</a>
    </li>
  

  </ul>
</div> <!-- end gc-topnav -->

    <div class="g-section g-tpl-170">

      <div class="g-unit g-first" id="gc-toc">
        <ul>
  <li><a href="../../../downloads.html">Downloads</a></li>
  <li><a href="http://code.google.com/status/appengine">System Status</a></li>
  <li><a href="http://code.google.com/p/googleappengine/issues/list">Issue Tracker</a></li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Getting Started</h2>
    <ul>
      <li><a href="../../whatisgoogleappengine.html">What Is Google App Engine?</a></li>
      <li><a href="../../java/gettingstarted/index.html">Java</a>
        <ul>
              <li><a href="../../java/gettingstarted/introduction.html">Introduction</a></li>
    <li><a href="../../java/gettingstarted/installing.html">Installing the Java SDK</a></li>
    <li><a href="../../java/gettingstarted/creating.html">Creating a Project</a></li>
    <li><a href="../../java/gettingstarted/usingusers.html">Using the Users Service</a></li>
    <li><a href="../../java/gettingstarted/usingjsps.html">Using JSPs</a></li>
    <li><a href="../../java/gettingstarted/usingdatastore.html">Using the Datastore with JDO</a></li>
    <li><a href="../../java/gettingstarted/staticfiles.html">Using Static Files</a></li>
    <li><a href="../../java/gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
      <li><a href="../gettingstarted/index.html">Python</a>
        <ul>
            <li><a href="../gettingstarted/introduction.html">Introduction</a></li>
  <li><a href="../gettingstarted/devenvironment.html">The Development Environment</a></li>
  <li><a href="../gettingstarted/helloworld.html">Hello, World!</a></li>
  <li><a href="../gettingstarted/usingwebapp.html">Using the webapp Framework</a></li>
  <li><a href="../gettingstarted/usingusers.html">Using the Users Service</a></li>
  <li><a href="../gettingstarted/handlingforms.html">Handling Forms With webapp</a></li>
  <li><a href="../gettingstarted/usingdatastore.html">Using the Datastore</a></li>
  <li><a href="../gettingstarted/templates.html">Using Templates</a></li>
  <li><a href="../gettingstarted/staticfiles.html">Using Static Files</a></li>
  <li><a href="../gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Java <sup class="new">Early Look</sup></h2>
    <ul>
          <li><a href="../../java/overview.html">Overview</a></li>
    <li><a href="../../java/runtime.html">Servlet Environment</a></li>
    <li><a href="../../java/datastore/index.html">Storing Data</a>
      <ul>
            <li><a href="../../java/datastore/overview.html">Overview</a></li>
    <li><a href="../../java/datastore/usingjdo.html">Using JDO</a></li>
    <li><a href="../../java/datastore/dataclasses.html">Defining Data Classes</a></li>
    <li><a href="../../java/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
    <li><a href="../../java/datastore/queriesandindexes.html">Queries and Indexes</a></li>
    <li><a href="../../java/datastore/transactions.html">Transactions</a></li>
    <li><a href="../../java/datastore/relationships.html">Relationships</a></li>
    <li><a href="../../java/datastore/usingjpa.html">Using JPA</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/datastore/package-summary.html">Low-level API</a></li>

      </ul>
    </li>
    <li><a href="../../java/apis.html">Services</a>
      <ul>
        <li><a href="../../java/memcache/index.html">Memcache</a>
          <ul>
                <li><a href="../../java/memcache/overview.html">Overview</a></li>
    <li><a href="../../java/memcache/usingjcache.html">Using JCache</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/memcache/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/urlfetch/index.html">URL Fetch</a>
          <ul>
                <li><a href="../../java/urlfetch/overview.html">Overview</a></li>
    <li><a href="../../java/urlfetch/usingjavanet.html">Using java.net</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/urlfetch/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/mail/index.html">Mail</a>
          <ul>
                <li><a href="../../java/mail/overview.html">Overview</a></li>
    <li><a href="../../java/mail/usingjavamail.html">Using JavaMail</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/mail/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../../java/images/index.html">Images</a>
          <ul>
                <li><a href="../../java/images/overview.html">Overview</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/images/package-summary.html">API Reference</a></li>

          </ul>
        </li>
        <li><a href="../../java/users/index.html">Google Accounts</a>
          <ul>
                <li><a href="../../java/users/overview.html">Overview</a></li>
    <li><a href="../../java/javadoc/com/google/appengine/api/users/package-summary.html">API Reference</a></li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../../java/javadoc/index.html">Javadoc Reference</a></li>
    <li><a href="../../java/jrewhitelist.html">JRE Class White List</a></li>
    <li><a href="../../java/config/index.html">Configuration</a>
      <ul>
            <li><a href="../../java/config/webxml.html">Deployment Descriptor</a></li>
    <li><a href="../../java/config/appconfig.html">App Config</a></li>
    <li><a href="../../java/config/indexconfig.html">Index Config</a></li>
    <li><a href="../../java/config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../../java/tools/index.html">Tools</a>
      <ul>
            <li><a href="../../java/tools/devserver.html">Development Server</a></li>
    <li><a href="../../java/tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../../java/tools/eclipse.html">Google Plugin for Eclipse</a></li>
    <li><a href="../../java/tools/ant.html">Using Apache Ant</a></li>

      </ul>
    </li>
    <li><a href="../../java/howto/index.html">How-To</a>
      <ul>
              <li><a href="../../java/howto/unittesting.html">Unit Testing</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Python</h2>
    <ul>
          <li><a href="../overview.html">Overview</a></li>
    <li><a href="../runtime.html">CGI Environment</a></li>
    <li><a href="../datastore/index.html">Storing Data</a>
      <ul>
             <li><a href="../datastore/overview.html">Overview</a></li>
     <li><a href="../datastore/entitiesandmodels.html">Entities and Models</a></li>
     <li><a href="../datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
     <li><a href="../datastore/keysandentitygroups.html">Keys and Entity Groups</a></li>
     <li><a href="../datastore/queriesandindexes.html">Queries and Indexes</a></li>
     <li><a href="../datastore/transactions.html">Transactions</a></li>
     <li><a href="../datastore/typesandpropertyclasses.html">Types and Property Classes</a></li>
     <li><a href="../datastore/gqlreference.html">GQL Reference</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../datastore/modelclass.html">Model</a></li>
         <li><a href="../datastore/expandoclass.html">Expando</a></li>
         <li><a href="../datastore/polymodelclass.html">PolyModel</a></li>
         <li><a href="../datastore/propertyclass.html">Property</a></li>
         <li><a href="../datastore/queryclass.html">Query</a></li>
         <li><a href="../datastore/gqlqueryclass.html">GqlQuery</a></li>
         <li><a href="../datastore/keyclass.html">Key</a></li>
         <li><a href="../datastore/functions.html">Functions</a></li>
         <li><a href="../datastore/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../apis.html">Services</a>
      <ul>
        <li><a href="../memcache/index.html">Memcache</a>
          <ul>
                 <li><a href="../memcache/overview.html">Overview</a></li>
      <li><a href="../memcache/usingmemcache.html">Using Memcache</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../memcache/clientclass.html">Client</a></li>
         <li><a href="../memcache/functions.html">Functions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../urlfetch/index.html">URL Fetch</a>
          <ul>
                 <li><a href="../urlfetch/overview.html">Overview</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../urlfetch/fetchfunction.html">The fetch Function</a></li>
         <li><a href="../urlfetch/responseobjects.html">Response Objects</a></li>
         <li><a href="../urlfetch/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../mail/index.html">Mail</a>
          <ul>
                 <li><a href="../mail/overview.html">Overview</a></li>
     <li><a href="../mail/sendingmail.html">Sending Mail</a></li>
     <li><a href="../mail/attachments.html">Attachments</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../mail/emailmessageclass.html">EmailMessage</a></li>
         <li><a href="../mail/emailmessagefields.html">Message Fields</a></li>
         <li><a href="../mail/functions.html">Functions</a></li>
         <li><a href="../mail/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../images/index.html">Images</a>
          <ul>
                 <li><a href="../images/overview.html">Overview</a></li>
     <li><a href="../images/installingPIL.html">Installing PIL</a></li>
     <li><a href="../images/usingimages.html">Using the Images API</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../images/imageclass.html">Image</a></li>
         <li><a href="../images/functions.html">Functions</a></li>
         <li><a href="../images/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../users/index.html">Google Accounts</a>
          <ul>
                 <li><a href="../users/overview.html">Overview</a></li>
     <li><a href="../users/userobjects.html">User Objects</a></li>
     <li><a href="../users/loginurls.html">Login URLs</a></li>
     <li><a href="../users/adminusers.html">Admin Users</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../users/userclass.html">User</a></li>
         <li><a href="../users/functions.html">Functions</a></li>
         <li><a href="../users/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="index.html">Configuration</a>
      <ul>
            <li><a href="appconfig.html">App Config</a></li>
    <li><a href="indexconfig.html">Index Config</a></li>
    <li><a href="cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../tools/index.html">Tools</a>
      <ul>
            <li><a href="../tools/devserver.html">Development Server</a></li>
    <li><a href="../tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../tools/uploadingdata.html">Uploading Data</a></li>
    <li><a href="../tools/webapp/index.html">webapp Framework</a>
      <ul>
             <li><a href="../tools/webapp/overview.html">Overview</a></li>
     <li><a href="../tools/webapp/running.html">Running the Application</a></li>
     <li><a href="../tools/webapp/requesthandlers.html">Request Handlers</a></li>
     <li><a href="../tools/webapp/requestdata.html">Request Data</a></li>
     <li><a href="../tools/webapp/buildingtheresponse.html">Building the Response</a></li>
     <li><a href="../tools/webapp/redirects.html">Redirects, Headers and Status Codes</a></li>
     

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../tools/webapp/requestclass.html">Request</a></li>
         <li><a href="../tools/webapp/responseclass.html">Response</a></li>
         <li><a href="../tools/webapp/requesthandlerclass.html">RequestHandler</a></li>
         <li><a href="../tools/webapp/wsgiapplicationclass.html">WSGIApplication</a></li>
         <li><a href="../tools/webapp/utilmodule.html">Utility Functions</a></li>
         
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../tools/libraries.html">Third-party Libraries</a></li>

      </ul>
    </li>
    <li><a href="../howto/index.html">How-To</a>
      <ul>
              <li><a href="../howto/usinggdataservices.html">Google Data Services</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Managing Your App</h2>
    <ul>
      <li><a href="../../theadminconsole.html">The Admin Console</a></li>
      <li><a href="../../quotas.html">Quotas</a></li>
      <li><a href="../../billing.html">Billing</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Resources</h2>
    <ul>
      <li><a href="../../../kb/index.html">FAQ</a></li>
      <li><a href="../../../articles/index.html">Articles</a></li>
      <li><a href="http://appengine-cookbook.appspot.com/">Cookbook</a></li>
      <li><a href="http://appgallery.appspot.com/">App Gallery</a></li>
      <li><a href="http://code.google.com/p/googleappengine/">SDK Code</a></li>
      <li><a href="http://code.google.com/p/google-app-engine-samples/">Sample Apps Code</a></li>
      <li><a href="../../../community.html">Discussion Groups</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><a href="../../roadmap.html">Product Roadmap</a></li>
  <li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Release Notes</a></li>
  <li><a href="../../revision_history.html">Revision History</a></li>
</ul>

        <a class="hidden" href="#gc-topnav-anchor">More Google App Engine resource links</a>
      </div>

      <div class="g-unit" id="gc-pagecontent">
        <h1 class="page_title">Python Application Configuration</h1>



<p>A Python App Engine application must have a configuration file named <code>app.yaml</code> that specifies how URL paths correspond to request handlers and static files.  It also contains information about the application code, such as the application ID and the latest version identifier.</p>

<ul>
  <li><a href="#About_app_yaml">About app.yaml</a></li>
  <li><a href="#Required_Elements">Required Elements</a></li>
  <li><a href="#Script_Handlers">Script Handlers</a></li>
  <li><a href="#Static_File_Handlers">Handlers for Static Files</a></li>
  <li><a href="#Secure_URLs">Secure URLs</a></li>
  <li><a href="#Requiring_Login_or_Administrator_Status">Requiring Login or Administrator Status</a></li>
  <li><a href="#Skipping_Files">Skipping Files</a></li>
  <li><a href="#Referring_to_the_Python_Library_Directory">Referring to the Python Library Directory</a></li>
  <li><a href="#Reserved_URLs">Reserved URLs</a></li>
</ul>


<h2 id="About_app_yaml">About app.yaml</h2>

<p>A Python app specifies runtime configuration, including versions and URLs, in a file named <code>app.yaml</code>.  The following is an example of an <code>app.yaml</code> file:</p>

<pre>
application: myapp
version: 1
runtime: python
api_version: 1

handlers:
- url: /
  script: home.py

- url: /index\.html
  script: home.py

- url: /stylesheets
  static_dir: stylesheets

- url: /(.*\.(gif|png|jpg))
  static_files: static/\1
  upload: static/(.*\.(gif|png|jpg))

- url: /admin/.*
  script: admin.py
  login: admin

- url: /.*
  script: not_found.py
</pre>

<p>The syntax of <code>app.yaml</code> is the YAML format.  For more information about this syntax, see <a href="http://www.yaml.org/">the YAML website</a> for more information.</p>

<p class="note"><b>Tip:</b> The YAML format supports comments.  A line that begins with a pound (<code>#</code>) character is ignored:<br/><code># This is a comment.</code></p>

<p>URL and file path patterns use <a href="http://en.wikipedia.org/wiki/Regular_expression%23Syntax&usg=__mBDvPGMNbDvCnmh1oLFnVOCuNwI=">POSIX extended regular expression syntax</a>, excluding collating elements and collation classes.  Back-references to grouped matches (e.g. <code>\1</code>) are supported, as are these Perl extensions: <code>\w \W \s \S \d \D</code>  (This is similar to <a href="http://www.google.com/intl/en/help/faq_codesearch.html#regexp">Codesite search</a>, plus back-reference support.)</p>


<h2 id="Required_Elements">Required Elements</h2>

<p>An <code>app.yaml</code> file must include one of each of the following elements:</p>

<dl>
  <dt><code>application</code></dt>
  <dd>
    <p>The application identifier.  This is the identifier you selected when you created the application in <a href="../../theadminconsole.html">the Administration Console</a>.</p>
    <pre>application: myapp</pre>
  </dd>

  <dt><code>version</code></dt>
  <dd>
    <p>A version specifier for the application code.  App Engine retains a copy of your application for each <code>version</code> used.  An administrator can change which major version of the application is public using <a href="../../theadminconsole.html">the Administration Console</a>, and can test non-public versions before making them public.</p>
    <p>Each version of an application retains its own copy of <code>app.yaml</code>.  When an application is uploaded, the version mentioned in the <code>app.yaml</code> file being uploaded is the version that gets created or replaced by the upload.</p>
    <pre>version: 1</pre>
  </dd>

  <dt><code>runtime</code></dt>
  <dd>
    <p>The name of the App Engine runtime environment used by this application.  At this time, App Engine has one runtime environment: <code>python</code></p>
    <pre>runtime: python</pre>
  </dd>

  <dt><code>api_version</code></dt>
  <dd>
    <p>The version of the API in the given runtime environment used by this application.  When Google releases a new version of a runtime environment's API, your application will continue to use the one for which it was written.  To upgrade your application to the new API, you change this value and upload the upgraded code.</p>
    <p>At this time, App Engine has one version of the <code>python</code> runtime environment: <code>1</code></p>
    <pre>api_version: 1</pre>
  </dd>

  <dt><code>handlers</code></dt>
  <dd>
    <p>A list of URL patterns and descriptions of how they should be handled.  App Engine can handle URLs by executing application code, or by serving static files uploaded with the code, such as images, CSS or JavaScript.</p>
    <p>Patterns are evaluated in the order they appear in the <code>app.yaml</code>, from top to bottom.  The first mapping whose pattern matches the URL is the one used to handle the request.</p>
    <p>There are two kinds of handlers: script handlers, and static file handlers.  A script handler runs a Python script in your application to determine the response for the given URL.  A static file handler returns the contents of a file, such as an image, as the response.</p>
    <p>See <a href="#Script_Handlers">Script Handlers</a> and <a href="#Static_File_Handlers">Handlers for Static Files</a> below for more information on this value.</p>
    <pre>handlers:
- url: /images
  static_dir: static/images

- url: /.*
  script: myapp.py
</pre>
  </dd>

</dl>


<h2 id="Script_Handlers">Script Handlers</h2>

<p>A script handler executes a Python script to handle the request that matches the URL pattern.  The mapping defines a URL pattern to match, and the script to be executed.</p>

<dl>
  <dt><code>url</code></dt>
  <dd>
    <p>The URL pattern, as a regular expression.  The expression can contain groupings that can be referred to in the file path to the script with regular expression back-references.</p>
    <p>For example, <code>/profile/(.*?)/(.*)</code> would match the URL <code>/profile/edit/manager</code> and use <code>edit</code> and <code>manager</code> as the first and second groupings.</p>
    <pre>handlers:
- url: /profile/(.*?)/(.*)
  script: /employee/\2/\1.py
</pre>
  </dd>

  <dt><code>script</code></dt>
  <dd>
    <p>The path to the script, from the application root directory.</p>
    <p>As in the previous example, with the groupings <code>edit</code> and <code>manager</code>, the script path <code>/employee/\2/\1.py</code> uses the full path <code>/employee/manager/edit.py</code>.</p>
  </dd>
</dl>

<p>The following examples map URLs to scripts:</p>

<pre>
handlers:

# The root URL (/) is handled by the index.py script.  No other URLs match this pattern.
- url: /
  script: index.py

# The URL /index.html is also handled by the index.py script.
- url: /index\.html
  script: index.py

# A regular expression can map parts of the URL to the file path of the script.
- url: /browse/(books|videos|tools)
  script: \1/catalog.py

# All other URLs use the not_found.py script.
- url: /.*
  script: not_found.py
</pre>


<h2 id="Static_File_Handlers">Handlers for Static Files</h2>

<p>Static files are files to be served directly to the user for a given URL, such as images, CSS stylesheets, or JavaScript source files.  Static file handlers describe which files in the application directory are static files, and which URLs serve them.</p>

<p>For efficiency, App Engine stores and serves static files separately from application files.  Static files are not available in the application's file system.  If you have data files that need to be read by the application code, the data files must be application files, and must not be matched by a static file pattern.</p>

<p>Unless told otherwise, web browsers retain files they load from a website for a limited period of time.  You can define a global default cache period for all static file handlers for an application by including the <code>default_expiration</code> element, a top-level element.  You can also configure a cache duration for specific static file handler.  (Script handlers can set cache durations by returning the appropriate HTTP headers to the browser.)</p>

<dl>
  <dt><code>default_expiration</code></dt>
  <dd>
    <p>The length of time a static file served by a static file handler ought to be cached in the user's browser, if the handler does not specify its own <code>expiration</code>.  The value is a string of numbers and units, separated by spaces, where units can be <code>d</code> for days, <code>h</code> for hours, <code>m</code> for minutes, and <code>s</code> for seconds.  For example, <code>"4d 5h"</code> sets cache expiration to 4 days and 5 hours after the file is first loaded by the browser.</p>
    <p><code>default_expiration</code> is optional.  If omitted, the default behavior is to allow the browser to determine its own cache duration.</p>
  </dd>
</dl>

<p>For example:</p>
<pre>
application: myapp
version: 1
runtime: python
api_version: 1

default_expiration: "4d 5h"

handlers:
  # ...
</pre>

<p>Static file handlers can be defined in two ways: as a directory structure of static files that maps to a URL path, or as a pattern that maps URLs to specific files.</p>


<h2>Static Directory Handlers</h2>

<p>A static directory handler makes it easy to serve the entire contents of a directory as static files.  Each file is served using the MIME type that corresponds with its filename extension unless overridden by the directory's <code>mime_type</code> setting.  All of the files in the given directory are uploaded as static files, and none of them can be run as scripts.</p>

<dl>
  <dt><code>url</code></dt>
  <dd>
    <p>A URL prefix.  This value uses regular expression syntax (and so regexp special characters must be escaped), but it should not contain groupings.  All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path.</p>
  </dd>

  <dt><code>static_dir</code></dt>
  <dd>
    <p>The path to the directory containing the static files, from the application root directory.  Everything after the end of the matched <code>url</code> pattern is appended to <code>static_dir</code> to form the full path to the requested file.</p>
    <p>All files in this directory are uploaded with the application as static files.</p>
  </dd>

  <dt><code>mime_type</code></dt>
  <dd>
    <p>Optional.  If specified, all files served by this handler will be served using the specified MIME type.  If not specified, the MIME type for a file will be derived from the file's filename extension.</p>
    <p>For more information about the possible MIME media types, see <a href="http://www.iana.org/assignments/media-types/">the IANA MIME Media Types website</a>.</p>
  </dd>

  <dt><code>expiration</code></dt>
  <dd>
    <p>The length of time a static file served by this handler ought to be cached in the user's browser.  The value is a string of numbers and units, separated by spaces, where units can be <code>d</code> for days, <code>h</code> for hours, <code>m</code> for minutes, and <code>s</code> for seconds.  For example, <code>"4d 5h"</code> sets cache expiration to 4 days and 5 hours after the file is first loaded by the browser.</p>
    <p><code>expiration</code> is optional.  If omitted, the application's <code>default_expiration</code> is used.</p>
  </dd>
</dl>

<p>For example:</p>
<pre>
handlers:

# All URLs beginning with /stylesheets are treated as paths to static files in
# the stylesheets/ directory.  Note that static_dir handlers do not use a
# regular expression for the URL pattern, only a prefix.
- url: /stylesheets
  static_dir: stylesheets
</pre>


<h2>Static File Pattern Handlers</h2>

<p>A static file handler associates a URL pattern with paths to static files uploaded with the application.  The URL pattern regular expression can define regular expression groupings to be used in the construction of the file path.  You can use this instead of <code>static_dir</code> to map to specific files in a directory structure without mapping the entire directory.</p>

<p>Static files cannot be the same as application code files.  If a static file path matches a path to a script used in a dynamic handler, the script will not be available to the dynamic handler.</p>

<p>The following <code>static_dir</code> and <code>static_files</code> handlers are equivalent:</p>
<pre>
- url: /images
  static_dir: static/images

- url: /images/(.*)
  static_files: static/images/\1
  upload: static/images/(.*)
</pre>

<dl>
  <dt><code>url</code></dt>
  <dd>
    <p>The URL pattern, as a regular expression.  The expression can contain groupings that can be referred to in the file path to the script with regular expression back-references.</p>
    <p>For example, <code>/item-(.*?)/category-(.*)</code> would match the URL <code>/item-127/category-fruit</code>, and use <code>127</code> and <code>fruit</code> as the first and second groupings.</p>
    <pre>handlers:
- url: /item-(.*?)/category-(.*)
  static_files: archives/\2/items/\1
</pre>
  </dd>

  <dt><code>static_files</code></dt>
  <dd>
    <p>The path to the static files matched by the URL pattern, from the application root directory.  The path can refer to text matched in groupings in the URL pattern.</p>
    <p>As in the previous example, <code>archives/\2/items/\1</code> inserts the second and first groupings matched in place of <code>\2</code> and <code>\1</code>, respectively.  With the pattern in the example above, the file path would be <code>archives/fruit/items/127</code>.</p>
  </dd>

  <dt><code>upload</code></dt>
  <dd>
    <p>A regular expression that matches the file paths for all files that will be referenced by this handler.  This is necessary because the handler cannot determine which files in your application directory correspond with the given <code>url</code> and <code>static_files</code> patterns.  Static files are uploaded and handled separately from application files.</p>
    <p>The example above might use the following <code>upload</code> pattern: <code>archives/(.*?)/items/(.*)</code></p>
  </dd>

  <dt><code>mime_type</code></dt>
  <dd>
    <p>Optional.  If specified, all files served by this handler will be served using the specified MIME type.  If not specified, the MIME type for a file will be derived from the file's filename extension.</p>
    <p>For more information about the possible MIME media types, see <a href="http://www.iana.org/assignments/media-types/">the IANA MIME Media Types website</a>.</p>
  </dd>

  <dt><code>expiration</code></dt>
  <dd>
    <p>The length of time a static file served by this handler ought to be cached in the user's browser.  The value is a string of numbers and units, separated by spaces, where units can be <code>d</code> for days, <code>h</code> for hours, <code>m</code> for minutes, and <code>s</code> for seconds.  For example, <code>"4d 5h"</code> sets cache expiration to 4 days and 5 hours after the file is first loaded by the browser.</p>
    <p><code>expiration</code> is optional.  If omitted, the application's <code>default_expiration</code> is used.</p>
  </dd>
</dl>

<p>For example:</p>

<pre>
handlers:

# All URLs ending in .gif .png or .jpg are treated as paths to static files in
# the static/ directory.  The URL pattern is a regexp, with a grouping that is
# inserted into the path to the file.
- url: /(.*\.(gif|png|jpg))
  static_files: static/\1
  upload: static/(.*\.(gif|png|jpg))
</pre>


<h2 id="Secure_URLs">Secure URLs</h2>

<p>Google App Engine supports secure connections via HTTPS for URLs using the <code>*.appspot.com</code> domain.  When a request accesses a URL using HTTPS, and that URL is configured to use HTTPS in the <code>app.yaml</code> file, both the request data and the response data are encrypted by the sender before they are transmitted, and decrypted by the recipient after they are received.  Secure connections are useful for protecting customer data, such as contact information, passwords, and private messages.</p>

<p class="note"><b>Note:</b> Google Apps domains do not currently support HTTPS.  HTTPS support is limited to apps accessed via <code>*.appspot.com</code> domains.  Accessing an HTTPS URL on a Google Apps domain will return a "host not found" error, and accessing a URL whose handler only accepts HTTPS (see below) using HTTP will return an HTTP 403 "Forbidden" error.  You can link to an HTTPS URL with the <code>*.appspot.com</code> domain for secure features, and use the Apps domain and HTTP for the rest of the site.</p>

<p>To configure a URL to accept secure connections, provide a <code>secure</code> parameter for the handler:</p>

<pre>
handlers:

- url: /youraccount/.*
  script: accounts.py
  login: required
  secure: always
</pre>

<p><code>secure</code> has 3 possible values:</p>
<ul>
  <li><code>never</code>. Requests for a URL that match this handler that use HTTPS are automatically redirected to the HTTP equivalent URL.  This is the default when <code>secure</code> is not provided for a handler.</li>
  <li><code>always</code>. Requests for a URL that match this handler that do not use HTTPS are automatically redirected to the HTTPS URL with the same path.  Query parameters are preserved for the redirect.</li>
  <li><code>optional</code>. Both HTTP and HTTPS requests with URLs that match the handler succeed without redirects. The application can examine the request to determine which protocol was used, and respond accordingly.</li>
</ul>

<p>When a user's HTTPS query is redirected to be an HTTP query, the query parameters are removed from the request.  This prevents a user from accidentally submitting query data over a non-secure connection that was intended for a secure connection.</p>

<p>Secure connections use more CPU and bandwidth than non-secure connections, and are therefore more expensive.  Secure connections are also slower than non-secure connections.</p>

<p>Any URL handler can use the <code>secure</code> setting, including script handlers and static file handlers.</p>

<p>The development web server does not support HTTPS connections.  It ignores the <code>secure</code> parameter, so paths intended for use with HTTPS can be tested using regular HTTP connections to the development web server.</p>

<p>When you test your app's HTTPS handlers using the versioned appspot.com URL, such as <code>https://1.latest.app-id.appspot.com/</code>, your browser will warn that the HTTPS certificate was not signed for that specific domain path.  If you accept the certificate for that domain, pages will load successfully.  Users will not see the certificate warning when accessing <code>https://app-id.appspot.com/</code>.</p>

<p>Google Accounts sign-in and sign-out are always performed using a secure connection, unrelated to how the application's URLs are configured.</p>


<h2 id="Requiring_Login_or_Administrator_Status">Requiring Login or Administrator Status</h2>

<p>Any URL handler can have a <code>login</code> setting to restrict visitors to only those users who have signed in, or just those users who are administrators for the application.  When a URL handler with a <code>login</code> setting matches a URL, the handler first checks whether the user has signed in to the application with a Google account.  If not, the user is redirected to the Google sign-in page, and is redirected back to the application URL after signing in or creating an account.</p>

<p>If the setting is <code>login: required</code>, once the user has signed in, the handler proceeds normally.</p>

<p>If the setting is <code>login: admin</code>, once the user has signed in, the handler checks whether the user is an administrator for the application.  If not, the user is given an error message.  If the user is an administrator, the handler proceeds.</p>

<p>If an application needs different behavior, the application can implement the user handling itself.  See <a href="../users/index.html">the Users API</a> for more information.</p>

<p>An example:</p>
<pre>
handlers:

- url: /profile/.*
  script: user_profile.py
  login: required

- url: /admin/.*
  script: admin.py
  login: admin

- url: /.*
  script: welcome.py
</pre>


<h2 id="Skipping_Files">Skipping Files</h2>

<p>Files in your application directory whose paths match a <code>static_dir</code> path or a <code>static_files</code> <code>upload</code> path are considered to be static files.  All other files in the application directory are considered to be application program and data files.</p>

<p>The <code>skip_files</code> element specifies which files in the application directory are not to be uploaded to App Engine.  The value is either a regular expression, or a list of regular expressions.  Any filename that matches any of the regular expression is omitted from the list of files to upload when the application is uploaded.</p>

<p><code>skip_files</code> has the following default value:</p>

<pre>
skip_files: |
 ^(.*/)?(
 (app\.yaml)|
 (app\.yml)|
 (index\.yaml)|
 (index\.yml)|
 (#.*#)|
 (.*~)|
 (.*\.py[co])|
 (.*/RCS/.*)|
 (\..*)|
 )$
</pre>

<p>The default pattern excludes the configuration files <code>app.yaml</code>, <code>app.yml</code>, <code>index.yaml</code>, <code>index.yml</code> (configuration is sent to the server separately), Emacs backup files with names of the form <code>#...#</code> and <code>...~</code>, <code>.pyc</code> and <code>.pyo</code> files, files in an <code>RCS</code> revision control directory, and Unix hidden files with names beginning with a dot (<code>.</code>).</p>

<p>If a new value is specified in <code>app.yaml</code>, it overrides this value.  To extend this pattern, copy and paste it into your configuration with your extensions.  For example, to skip files whose names end in <code>.bak</code> in addition to the default patterns, you can use the following list value for <code>skip_files</code>:</p>

<pre>
skip_files:
- ^(.*/)?app\.yaml
- ^(.*/)?app\.yml
- ^(.*/)?index\.yaml
- ^(.*/)?index\.yml
- ^(.*/)?#.*#
- ^(.*/)?.*~
- ^(.*/)?.*\.py[co]
- ^(.*/)?.*/RCS/.*
- ^(.*/)?\..*
- ^(.*/)?.*\.bak$
</pre>


<h2 id="Referring_to_the_Python_Library_Directory">Referring to the Python Library Directory</h2>

<p>You can refer to the Python library directory in an <code>app.yaml</code> script path using <code>$PYTHON_LIB</code>.  This is only useful for setting up handlers whose scripts are included in the App Engine libraries.</p>

<p>For example, <code>$PYTHON_LIB/google/appengine/ext/admin</code> is an administrative application similar to the developer console feature of <a href="../tools/devserver.html">the development web server</a> that can run as part of your application on App Engine itself.  To set it up, include configuration for a script handler using its path:</p>

<pre>
handlers:

- url: /admin/.*
  script: $PYTHON_LIB/google/appengine/ext/admin
  login: admin
</pre>


<h2 id="Reserved_URLs">Reserved URLs</h2>

<p>Several URL paths are reserved by App Engine for features or administrative purposes.  Script handler and static file handler paths will never match these paths.</p>

<p>The following URL paths are reserved:</p>

<ul>
  <li><code>/_ah/</code></li>
  <li><code>/form</code></li>
</ul>



      </div><!-- end gc-pagecontent -->
   </div><!-- end gooey wrapper -->

    </div> <!-- end codesite content -->

<div id="gc-footer" dir="ltr">
  <div class="text">
    
      <div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
  Except as otherwise <a
  href="http://code.google.com/policies.html#restrictions">noted</a>,
  the content of this page is licensed under the <a rel="license"
  href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
  Attribution 2.5 License</a>, and code samples are licensed under the
  <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">Apache
  2.0 License</a>.
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" 
              xmlns:dc="http://purl.org/dc/elements/1.1/"
              xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <Work rdf:about="">
    <license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
  </Work>
  <License rdf:about="http://creativecommons.org/licenses/by/2.5/">
    <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
    <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
    <requires rdf:resource="http://web.resource.org/cc/Notice"/>
    <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
    <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
  </License>
</rdf:RDF> -->
</div>
Java is a registered trademark of Sun Microsystems, Inc.</div>
    
    &copy;2009 Google -
    <a href="http://code.google.com">Code Home</a> -
    <a href="http://www.google.com/accounts/TOS">Terms of Service</a> -
    <a href="http://www.google.com/privacy.html">Privacy Policy</a> -
    <a href="http://code.google.com/more">Site Directory</a>
    <br /> <br />
    Google Code offered in:
    <a href="http://code.google.com/intl/en">English</a> -
    <a href="http://code.google.com/intl/es">Español</a> -
    <a href="http://code.google.com/intl/ja">日本語</a> -
    <a href="http://code.google.com/intl/ko">한국어</a> -
    <a href="http://code.google.com/intl/pt-BR">Português</a> -
    <a href="http://code.google.com/intl/ru">Pусский</a> -
    <a href="http://code.google.com/intl/zh-CN">中文(简体)</a> -
    <a href="http://code.google.com/intl/zh-TW">中文(繁體)</a>
  </div>
</div><!-- end gc-footer -->

</div><!-- end gc-containter -->

<script type="text/javascript">CODESITE_CSITimer['load'].tick('ats');</script>
<script src="../../../../js/codesite_tail.pack.04102009.js" type="text/javascript"></script>






  </body>
</html>


